<template>
  <a-spin :spinning="spinning">
    <div class="main-box">
      <div class="left-box" style="min-width: 200px;">
        <a-card :body-style="{ padding: '0px', 'min-height': 'calc(100vh - 100px)' }">
          <!-- <a-button size="large" style="margin: 10px auto; border-radius: 3px !important" v-has="'role:addRole'" ghost type="primary" block -->
          <a-button size="large" style="margin: 10px auto; border-radius: 3px !important" ghost type="primary" block @click="showWindow(undefined, '', '')">
            新建角色
          </a-button>
          <a-menu v-if="activeMenu" style="width: 100%" :default-selected-keys="[activeMenu]" mode="inline" @click="handleClick">
            <a-menu-item v-for="item in roleList" :key="item.id">
              <span>{{ item.roleName }}</span>
              <!-- <span v-if="item.id == activeMenu && item.internalRoleFlag === 0"> -->
              <span v-if="item.id == activeMenu&&item.internalRoleFlag != 1">
                <a-icon type="edit" @click="showWindow(item.id, item.roleName, item.roleCode)" />
                <a-popconfirm title="确定删除吗？" ok-text="确定" cancel-text="取消" @confirm="deleteRole(item.id)">
                  <a-icon type="delete" />
                </a-popconfirm>
              </span>
            </a-menu-item>
          </a-menu>
        </a-card>
      </div>
      <div class="right-box">
        <a-card :body-style="{ padding: '10px', 'min-height': 'calc(100vh - 100px)' }">
          <div style="text-align: right; margin-bottom: 10px">
            <a-button type="primary" @click="save"> 保存 </a-button>
          </div>
          <div style="height:calc(100vh - 150px);overflow-y: scroll;">
            <a-table bordered :scroll="{ x: 800 }" ref="table" childrenColumnName="ppp" :columns="tableColumn" :dataSource="treeList" class="j-table-force-nowrap"
              :pagination="false">
              <!-- 一级菜单 -->
              <span slot="slotTitle" slot-scope="text, record, index" v-if="!record.hidden">
                <a-checkbox @change="oneChange(record, index)" :checked="record.select">{{ text }} </a-checkbox>
              </span>
              <!-- 二级菜单 -->
              <div slot="children" slot-scope="text, record, indexs" style="margin: -16px">
                <div v-for="(twoItem, twoIndex) in record.children" :key="twoItem.key" class="children-box flexBox" :style="{height:boxHeight(twoItem)}">
                  <a-checkbox @change="twoChange(record,twoItem, twoIndex, indexs)" :checked="twoItem.select" :style="twoHeight(twoItem)">{{ twoItem.slotTitle }}
                  </a-checkbox>
                </div>
              </div>
              <!-- 三级菜单 -->
              <div slot="threeChildren" slot-scope="text, record, indexs" style="margin: -16px">
                <div v-for="(twoItem, twoIndex) in record.children" :key="twoItem.key" class="children-box" :style="{height:boxHeight(twoItem)}">
                  <div v-for="(threeItem, threeIndex) in twoItem.children" :key="threeItem.key" class="children-box columnFlexBox">
                    <a-checkbox @change="threeChange(record,twoItem, twoIndex,threeItem,threeIndex, indexs)" :checked="threeItem.select">
                      {{ threeItem.slotTitle }}
                    </a-checkbox>
                  </div>
                </div>
              </div>
              <!-- 功能权限 -->
              <div slot="childrenBtn" slot-scope="text, record, indexs" style="margin: -16px">
                <div v-for="(item, indexchildren) in record.children" :key="item.id" class="children-box" :style="goHeights(item)" style="text-align: left">
                  <div v-if="record.children[indexchildren].children.length == 0">
                    <div style="float: left; width: 100%; height: 25px; padding: 0px 10px">
                      <a-checkbox v-if="item.buttons.length > 0" @change="onChangeAll(item, record, indexchildren, indexs)" :checked="goAllCheck(item)">全选
                      </a-checkbox>
                    </div>
                    <div v-for="(items, lastIndex) in item.buttons" :key="items.id" v-show="!items.hidden" :style="btns(items)">
                      <a-checkbox @change="onChangeChildrenBtn(item, items, indexchildren, lastIndex, indexs)" :checked="items.select" v-if="!items.hidden">
                      </a-checkbox>
                      {{ items.name }}
                    </div>
                  </div>
                  <div v-else>
                    <div v-for="(each,indexEach) in item.children" :key="indexEach" :style="goHeightTwo(item)" class="children-box">
                      <div style="float: left; width: 100%; height: 25px; padding: 0px 10px">
                        <a-checkbox v-if="each.buttons.length > 0" @change="threeChangeAll(item, record, indexchildren, indexs,each,indexEach)"
                          :checked="threeAllCheck(each)">全选
                        </a-checkbox>
                      </div>
                      <div v-for="(items, lastIndex) in each.buttons" :key="items.id" v-show="!items.hidden" :style="btns(items)">
                        <a-checkbox @change="threeBtn(item, items, indexchildren, lastIndex, indexs,each,indexEach)" :checked="items.select" v-if="!items.hidden">
                        </a-checkbox>
                        {{ items.name }}
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <!-- 数据权限 -->
              <div slot="dataRoles" slot-scope="text, record" style="margin: -16px">
                <div v-for="item in record.children" :key="item.id" :style="goDataHeights(item)" class="children-box">
                  <div v-if="item.children.length==0">
                    <a-radio-group v-model="item.dataRuleIds" size="small">
                      <a-radio v-for="(items, index) in item.permRuleList" :key="index" :style="radioStyle" :value="items.id">
                        {{ items.ruleName }}
                      </a-radio>
                    </a-radio-group>
                  </div>
                  <div v-else>
                    <div v-for="(each,indexEach) in item.children" :key="indexEach" :style="getDataHigh(item)" class="children-box">
                      <a-radio-group v-model="each.dataRuleIds" size="small">
                        <a-radio v-for="(tag, indexTag) in each.permRuleList" :key="indexTag" :style="radioStyle" :value="tag.id">
                          {{ tag.ruleName }}
                        </a-radio>
                      </a-radio-group>
                    </div>
                  </div>
                </div>
              </div>
            </a-table>
          </div>
        </a-card>
      </div>
    </div>
    <a-modal :title="formParam.id ? '编辑角色' : '新建角色'" :visible="visible" :width="600" :body-style="{ padding: '30px 50px 0px 50px' }" @cancel="handleCancel">
      <a-form-model ref="formParam" :model="formParam" :rules="{
          roleName: [
            { required: true, message: '请输入角色名称', trigger: 'change' },
            { min: 1, max: 6, message: '长度在1-6个字符', trigger: 'blur' },
          ],
          roleCode: [{ required: true, validator: checkNum, trigger: 'change' }],
        }" layout="vertical">
        <a-form-model-item ref="roleName" label="角色名称" prop="roleName">
          <a-input placeholder="最多允许输入6个字符" v-model="formParam.roleName" />
        </a-form-model-item>
        <a-form-model-item ref="roleCode" label="角色编码" prop="roleCode">
          <a-input placeholder="最多允许输入20个字符" v-model="formParam.roleCode" />
        </a-form-model-item>
      </a-form-model>
      <template slot="footer">
        <div style="width: 100%; text-align: left; padding-left: 34px">
          <a-button @click="
              visible = false
              $refs.formParam.resetFields()
            ">取消</a-button>
          <a-button type="primary" :loading="btnLoading" @click="handleOk">确定</a-button>
        </div>
      </template>
    </a-modal>
  </a-spin>
</template>

<script>
import {
  roleGetRoles,
  roleCheckRoleCode,
  roleAdd,
  roleDelete,
  roleEdit,
  roleQueryTreeList,
  saveRolePermissions,
  roleDatarule,
} from '@/api/authorityManagement'
export default {
  name: 'AuthorityManagementRoleManager',
  data() {
    return {
      spinning: false,
      roleList: [],
      activeMenu: null,
      visible: false,
      formParam: {
        id: undefined,
        roleName: '',
        roleCode: '',
      },
      btnLoading: false,
      treeList: [],
      tableLoading: false,
      tableColumn: [
        {
          title: '一级菜单',
          key: '1',
          dataIndex: 'slotTitle',
          width: '100px',
          scopedSlots: { customRender: 'slotTitle' },
        },
        {
          title: '二级菜单',
          key: '2',
          dataIndex: 'id',
          width: '100px',
          scopedSlots: { customRender: 'children' },
        },
        {
          title: '三级菜单',
          key: '6',
          dataIndex: 'value',
          width: '100px',
          scopedSlots: { customRender: 'threeChildren' },
        },
        {
          title: '功能权限',
          key: '3',
          width: '250px',
          dataIndex: 'key',
          scopedSlots: { customRender: 'childrenBtn' },
        },
        {
          title: '数据权限',
          width: '200px',
          key: '4',
          scopedSlots: { customRender: 'dataRoles' },
        },
      ],
      radioStyle: {
        display: 'block',
        height: '30px',
        lineHeight: '30px',
      },
    }
  },
  created() {
    this.getRoles()
  },
  methods: {
    save() {
      this.spinning = true
      let obj = {
        roleId: this.activeMenu,
        roleTree: this.treeList,
      }
      saveRolePermissions(obj).then((res) => {
        if (res.success) {
          this.$notification.success({ message: '系统提示', description: res.message })
        } else {
          this.$notification.error({ message: '系统提示', description: res.message })
        }
        this.spinning = false
        this.getTreeData()
      })
      console.log(this.treeList)
    },
    btns(item) {
      if (item.name.length > 8) {
        return ' float: left; width: 100%;height:30px;padding:0px 10px'
      } else {
        return ' float: left; width: 40%;height:30px;padding:0px 10px'
      }
    },
    boxHeight(twoItem) {
      let heightNum = 0
      if (twoItem.children.length > 0) {
        heightNum = 135 * twoItem.children.length
      } else {
        heightNum = 135
      }
      return heightNum + 'px'
    },
    twoHeight(twoItem) {
      if (twoItem.children.length >= 5) {
        return `height:${twoItem.children.length * 25 + 25}px;line-height: ${
          twoItem.children.length > 0 ? twoItem.children.length * 25 + 25 : 25
        }px;`
      } else {
        return `height:${twoItem.children.length * 40 + 40}px;line-height: ${
          twoItem.children.length > 0 ? twoItem.children.length * 40 + 40 : 40
        }px;`
      }
    },
    threeHeight(threeItem) {
      if (threeItem.buttons.length >= 5) {
        return `height:${threeItem.buttons.length * 25 + 25}px;line-height: ${
          threeItem.buttons.length > 0 ? threeItem.buttons.length * 25 + 25 : 25
        }px;`
      } else {
        return `height:${threeItem.buttons.length * 40 + 40}px;line-height: ${
          threeItem.buttons.length > 0 ? threeItem.buttons.length * 40 + 40 : 40
        }px;`
      }
    },
    goHeights(item) {
      if (item.children.length == 0) {
        if (item.buttons.length >= 5) {
          return `line-height: 56px;`
        } else {
          return `padding: 15px 0;`
        }
      }
    },
    goHeightTwo(item) {
      if (item.children.length == 0) {
        return `line-height: 56px;`
      } else {
        return `padding: 15px 0;`
      }
    },
    goDataHeights(item) {
      if (item.children.length == 0) {
        if (item.buttons.length >= 5) {
          return `height:${item.buttons.length * 25 + 25}px;line-height: 56px;`
        } else {
          return `height:${item.buttons.length * 40 + 40}px;padding: 15px 0;`
        }
      }
    },
    getDataHigh(item) {
      if (item.children.length == 0) {
        return `line-height: 56px;height:135px`
      } else {
        return `padding: 15px 0;height:135px`
      }
    },
    goHeightRoles(item) {
      if (item.buttons.length >= 5) {
        return `height:${item.buttons.length * 25 + 25}px;line-height: ${
          item.buttons.length > 0 ? item.buttons.length * 25 : 25
        }px;`
      } else {
        return `height:${item.buttons.length * 40 + 40}px;`
      }
    },
    oneChange(oneItem, oneIndex) {
      //点击顶部的菜单
      this.treeList[oneIndex].select = !oneItem.select
      //下级赋值
      for (let j = 0; j < this.treeList[oneIndex].children.length; j++) {
        this.treeList[oneIndex].children[j].select = oneItem.select
        for (let k = 0; k < this.treeList[oneIndex].children[j].children.length; k++) {
          this.treeList[oneIndex].children[j].children[k].select = oneItem.select
          this.treeList[oneIndex].children[j].children[k].buttons.forEach((item) => {
            item.select = oneItem.select
          })
        }
        for (let s = 0; s < this.treeList[oneIndex].children[j].buttons.length; s++) {
          this.treeList[oneIndex].children[j].buttons[s].select = oneItem.select
        }
      }
    },
    goAllCheck(item) {
      let arr = item.buttons.filter((item) => item.select == true)
      if (arr.length == item.buttons.length) {
        return true
      } else {
        return false
      }
    },
    threeAllCheck(each) {
      let arr = each.buttons.filter((item) => item.select == true)
      if (arr.length == each.buttons.length) {
        return true
      } else {
        return false
      }
    },
    onChangeAll(item, record, indexchildren, indexs) {
      let arr = item.buttons.filter((item) => item.select == true)
      if (arr.length == item.buttons.length) {
        this.set(item.buttons, indexchildren, indexs, false)
      } else {
        this.treeList[indexs].children[indexchildren].select = true
        this.treeList[indexs].select = true
        this.set(item.buttons, indexchildren, indexs, true)
      }
    },
    set(item, indexchildren, indexs, v) {
      for (let index = 0; index < item.length; index++) {
        this.treeList[indexs].children[indexchildren].buttons[index].select = v
      }
      this.treeList = [...this.treeList]
    },
    threeChangeAll(item, record, indexchildren, indexs, each, indexEach) {
      let arr = each.buttons.filter((item) => item.select == true)
      if (arr.length == each.buttons.length) {
        this.setThree(each.buttons, indexchildren, indexEach, indexs, false)
      } else {
        this.treeList[indexs].children[indexchildren].children[indexEach].select = true
        this.treeList[indexs].select = true
        this.treeList[indexs].children[indexchildren].select = true
        this.setThree(each.buttons, indexchildren, indexEach, indexs, true)
      }
    },
    setThree(item, indexchildren, indexEach, indexs, v) {
      for (let index = 0; index < item.length; index++) {
        this.treeList[indexs].children[indexchildren].children[indexEach].buttons[index].select = v
      }
      this.treeList = [...this.treeList]
    },
    onChangeChildrenBtn(item, items, indexchildren, lastIndex, indexs) {
      console.log('radio checked', item, items, indexchildren, lastIndex, indexs)
      this.treeList[indexs].children[indexchildren].buttons[lastIndex].select = !items.select
      this.treeList = [...this.treeList]
      let arr = item.buttons.filter((item) => item.select == true)
      if (arr.length === 0) {
        this.treeList = [...this.treeList]
      } else {
        this.treeList[indexs].children[indexchildren].select = true
        this.treeList[indexs].select = true
        this.treeList = [...this.treeList]
      }
    },
    threeBtn(item, items, indexchildren, lastIndex, indexs, each, indexEach) {
      this.treeList[indexs].children[indexchildren].children[indexEach].buttons[lastIndex].select = !items.select
      this.treeList = [...this.treeList]
      let arr = each.buttons.filter((item) => item.select == true)
      if (arr.length === 0) {
        this.treeList = [...this.treeList]
      } else {
        this.treeList[indexs].children[indexchildren].children[indexEach].select = true
        this.treeList[indexs].children[indexchildren].select = true
        this.treeList[indexs].select = true
        this.treeList = [...this.treeList]
      }
    },
    twoChange(rootItem, towItem, twoIndex, rootIndex) {
      console.log(rootItem, '1238888')
      this.treeList[rootIndex].children[twoIndex].select = !towItem.select
      for (let k = 0; k < this.treeList[rootIndex].children[twoIndex].children.length; k++) {
        this.treeList[rootIndex].children[twoIndex].children[k].select = towItem.select
        this.treeList[rootIndex].children[twoIndex].children[k].buttons.forEach((item) => {
          item.select = towItem.select
        })
      }
      //下级赋值
      for (let s = 0; s < this.treeList[rootIndex].children[twoIndex].buttons.length; s++) {
        this.treeList[rootIndex].children[twoIndex].buttons[s].select = towItem.select
      }

      this.treeList = [...this.treeList]
      let arr = rootItem.children.filter((item) => item.select == true)
      console.log(arr, 'rootItem')
      if (arr.length === 0) {
        this.treeList[rootIndex].select = false
      } else {
        this.treeList[rootIndex].select = true
      }
    },
    threeChange(rootItem, twoItem, twoIndex, treeItem, threeIndex, rootIndex) {
      this.treeList[rootIndex].children[twoIndex].children[threeIndex].select = !treeItem.select
      this.treeList = [...this.treeList]
      let arr = twoItem.children.filter((item) => item.select == true)
      this.treeList[rootIndex].children[twoIndex].children[threeIndex].buttons.forEach((button) => {
        button.select = treeItem.select
      })
      console.log(arr, 'rootItem')
      if (arr.length === 0) {
        this.treeList[rootIndex].children[twoIndex].select = false
        let newArr = rootItem.children.filter((item) => item.select == true)
        if (newArr.length === 0) {
          this.treeList[rootIndex].select = false
        } else {
          this.treeList[rootIndex].select = true
        }
      } else {
        this.treeList[rootIndex].children[twoIndex].select = true
        this.treeList[rootIndex].select = true
      }
    },
    async getRoles() {
      try {
        this.spinning = true
        const res = await roleGetRoles()
        if (res.result && res.result.length) {
          if (!this.activeMenu) {
            //首次选中
            this.activeMenu = res.result[0].id
          }
          this.getTreeData()
          this.roleList = res.result
        }
        this.spinning = false
      } catch (e) {
        this.spinning = false
        console.log(e)
      }
    },
    showWindow(id, name, code) {
      this.formParam.id = id
      this.formParam.roleName = name
      this.formParam.roleCode = code
      this.visible = true
    },
    handleClick(e) {
      this.activeMenu = e.key

      this.getTreeData()
    },
    async deleteRole(id) {
      try {
        const res = await roleDelete({ id: id })
        if (res.success) {
          this.activeMenu = ''
          this.getRoles()
          this.$notification.success({ message: '系统提示', description: res.message })
        } else {
          this.$notification.error({ message: '系统提示', description: res.message })
        }
      } catch (e) {}
    },
    async checkNum(a, b, c) {
      try {
        if (b === '') {
          c('请输入角色编码')
        }
        if (b.length > 20) {
          c('长度在1-20个字符')
        }
        if (!/^[a-zA-Z0-9_]+$/.test(b)) {
          c('请输入正确的编码')
        }
        const res = await roleCheckRoleCode({ id: this.formParam.id, roleCode: this.formParam.roleCode })
        if (!res.success) {
          c(res.message)
        }
      } catch (error) {
        c('查重失败')
      }
    },
    handleOk() {
      this.$refs.formParam.validate(async (valid) => {
        if (valid) {
          const api = this.formParam.id ? roleEdit : roleAdd
          try {
            this.btnLoading = true
            const res = await api(this.formParam)
            if (res.success) {
              this.visible = false
              this.getRoles()
              this.$refs.formParam.resetFields()
              this.$notification.success({ message: '系统提示', description: res.message })
            } else {
              this.$notification.error({ message: '系统提示', description: res.message })
            }
            this.btnLoading = false
          } catch (e) {
            this.btnLoading = false
            this.$notification.error({ message: '系统提示', description: e.toString() })
          }
        }
      })
    },
    handleCancel() {
      this.visible = false
      this.$refs.formParam.resetFields()
    },
    async getTreeData() {
      try {
        this.spinning = true
        const res = await roleQueryTreeList({ roleId: this.activeMenu })
        this.treeList = res.result.treeList
        console.log(this.treeList)

        this.spinning = false
      } catch (e) {
        this.spinning = false
      }
    },
    getDataRole(param) {
      return new Promise(async (resolve, reject) => {
        const res = await roleDatarule(param)
        if (res.success) {
          resolve(res.result.datarule)
        } else {
          resolve([])
        }
      })
    },
  },
}
</script>

<style >
.ant-table-thead > tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td,
.ant-table-tbody > tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td,
.ant-table-thead > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td,
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
  background: #fff;
}
</style>
<style lang="less" scoped>
.children-box {
  // margin:0px -16px;
  min-height: 135px;
  // line-height: 30px;
  border-bottom: 1px solid #e8e8e8;
  // border-bottom: 1px solid red;
}

.children-box:last-child {
  // margin:0px -16px;
  // height: 50px;
  // line-height: 30px;
  border-bottom: none;
}
.children-boxs {
  line-height: 30px;
  // border-bottom: 1px solid #fff;
}
.main-box {
  display: flex;
  flex-flow: row nowrap;
  .left-box {
    width: 320px;
    overflow: scroll;
    height: calc(100vh - 75px);
    .ant-menu-item-selected {
      display: flex;
      justify-content: space-between;
      background: #d2e9ff;
    }
  }
  .right-box {
    margin-left: 20px;
    flex: 1;
    overflow: scroll;
    height: calc(100vh - 75px);
  }
}
.flexBox {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding-left: 16px;
  box-sizing: border-box;
}
.columnFlexBox {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  flex-direction: column;
  padding: 16px;
  box-sizing: border-box;
  overflow-y: auto;
}
/deep/ .j-table-force-nowrap td {
  white-space: inherit;
}
</style>